package httpserver

import (
	"context"
	"errors"
	"github.com/gin-gonic/gin"
	"net/http"
	"os"
	"os/signal"
	"prize/go-common/logger"
	"prize/go-common/server"
	"sync"
	"syscall"
	"time"
)

type Sever struct {
	ctx       context.Context
	instance  *http.Server
	ginEngine *gin.Engine
	//taskManager *cron.Task
	option     server.Option
	isShutDown bool
	onShutdown []func()
}

func NewHttpServer(ctx context.Context, o server.Option) *Sever {
	s := Sever{
		ctx:        ctx,
		option:     o,
		isShutDown: false,
	}

	return &s
}

func (s *Sever) start() {
	go func() {
		if err := s.instance.ListenAndServe(); err != nil && errors.Is(err, http.ErrServerClosed) {
			logger.Warn("监听服务：\n", err)
		}
	}()
	s.registerSignal()
}

func (s *Sever) Shutdown() {
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	if err := s.instance.Shutdown(ctx); err != nil {
		logger.Warn("服务关闭", err)
	}

	s.isShutDown = true
	wg := sync.WaitGroup{}
	for _, f := range s.onShutdown {
		wg.Add(1)
		go func(f func()) {
			f()
			wg.Done()
		}(f)
	}

	wg.Wait()
	logger.Info("Shutdown ......complete")
}

func (s *Sever) RegisterOnShutdown(f func()) {
	s.onShutdown = append(s.onShutdown, f)
}

func (s *Sever) RegisterHandler(method, uri string, logic func(ctx *RequestCtx)) {
	s.ginEngine.Handle(method, uri, func(c *gin.Context) {
		localContext := &RequestCtx{
			Request: c.Request,
			Writer:  c.Writer,
		}
		logic(localContext)
	})
}

func (s *Sever) RegisterMiddleware(handler func(ctx *RequestCtx) bool) {
	s.ginEngine.Use(func(c *gin.Context) {
		localContext := &RequestCtx{
			Request: c.Request,
			Writer:  c.Writer,
		}
		if handler(localContext) {
			c.Next()
		} else {
			c.Abort()
		}
	})
}

func (s *Sever) setLogFileManager() {
	if s.option.Log.Target == server.ConsoleTarget {
		return
	}

	// 日志文件轮转
	//logFileManager := log
}

func (s *Sever) registerSignal() {
	quit := make(chan os.Signal)
	signal.Notify(quit, syscall.SIGKILL, syscall.SIGTERM, syscall.SIGINT)
	<-quit
	logger.Warn("开始关闭服务器")

}
